package com.hibase.core.mybatis.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hibase.common.entity.PageBase;
import com.hibase.common.exception.HibaseAssert;
import com.hibase.core.mybatis.entity.BaseDO;
import com.hibase.core.mybatis.registrar.HibaseMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

/**
 * base service
 *
 * @author hufeng
 * @date 2019/01/15
 */
@Slf4j
public abstract class BaseServiceImpl<M extends HibaseMapper<T>, T extends BaseDO> extends ServiceImpl<M, T> implements BaseService<T> {

    @Override
    public PageInfo<T> page(PageBase pageBase, Wrapper<T> queryWrapper) {
        Page<T> page = PageHelper.startPage(pageBase.getCurrentPage(), pageBase.getPageSize());
        this.baseMapper.selectList(this.quickLookQuery(pageBase, (QueryWrapper<T>) queryWrapper));
        PageInfo<T> pageInfo = new PageInfo<>(page);
        return pageInfo;
    }

    /**
     * 通用保存
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public T store(T entity) {
        this.saveOrUpdate(entity);
        return entity;
    }

    /**
     * 根据id查询记录
     *
     * @param id
     * @param throwException true 为空抛出异常，false 返回null
     * @return
     */
    @Override
    public T getById(Serializable id, boolean throwException) {
        T t = baseMapper.selectById(id);
        HibaseAssert.isFalse(ObjectUtil.isEmpty(t) && throwException,
                "{}记录不存在",id);
        return t;
    }

    @Override
    public boolean deleteBy(String id) {
        return this.removeById(id);
    }

    /**
     * 通用批量保存
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean storeBatch(Collection<T> entityList, int batchSize) {
        return this.saveOrUpdateBatch(entityList, batchSize);
    }

    /**
     * 通用批量保存( 空集合是否判断异常)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean storeBatch(Collection<T> entityList, boolean throwException){
        if (!throwException){
            if (CollUtil.isEmpty(entityList)){
                return false;
            }else {
                return this.saveOrUpdateBatch(entityList);
            }
        }else{
            return this.saveOrUpdateBatch(entityList);
        }
    }

    /**
     * 通用批量保存
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean storeBatch(Collection<T> entityList) {
        return this.saveOrUpdateBatch(entityList);
    }

    /**
     * 根据条件逻辑删除
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBy(Wrapper<T> queryWrapper) {
        return this.remove(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBy(Collection<? extends Serializable> ids, boolean throwException) {
        return this.removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBy(Collection<? extends Serializable> ids) {
        return this.removeByIds(ids);
    }

    @Override
    public boolean deleteBy(T object) {
        return this.removeById(object.getId());
    }

    @Override
    public PageInfo<Map<String, Object>> pageMaps(PageBase pageBase, Wrapper<T> queryWrapper) {
        Page<Map<String, Object>> page = PageHelper.startPage(pageBase.getCurrentPage(), pageBase.getPageSize());
        this.baseMapper.selectMaps(queryWrapper);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(page);
        return pageInfo;
    }

    /**
     * @Title: BaseServiceImpl
     * @Description: 支持快速查找分页
     * @author TimBrian
     * @since Jun 2, 2021 6:48:01 PM
     * @param pageBase
     * @param queryWrapper
     * @return
     */
    public QueryWrapper<T> quickLookQuery(PageBase pageBase, QueryWrapper<T> queryWrapper){
        //快速查询
        if (StrUtil.isNotBlank(pageBase.getKeyWord()) && StrUtil.isNotBlank(pageBase.getQueryParams())){
            String[] split = pageBase.getQueryParams().split(",");
            for (String sqlCond : split) {
                //匹配到大写 替换然后 转换成小写
                sqlCond = sqlCond.replaceAll("[A-Z]", "_$0").toLowerCase();
                boolean contains = sqlCond.contains("%");
                if (!contains) {
                    queryWrapper.eq(sqlCond, pageBase.getKeyWord()).or();
                } else {
                    //首匹配
                    int frist = sqlCond.indexOf("%");
                    int last = sqlCond.lastIndexOf("%");
                    sqlCond = sqlCond.replaceAll("%", "");
                    if (frist != -1 && frist == 0 && last > 0) {
                        queryWrapper.like(sqlCond, pageBase.getKeyWord()).or();
                    }else if (frist != -1 && frist > 0) {
                        //右关联
                        queryWrapper.likeRight(sqlCond, pageBase.getKeyWord()).or();
                    }else if (frist == 0 && last == 0) {
                        //左关联
                        queryWrapper.likeLeft(sqlCond, pageBase.getKeyWord()).or();
                    }

                }
            }
        }
        return queryWrapper;
    }
}
